import type { PropType, VNodeChild, App } from 'vue'
import { defineComponent } from "vue";
import Sunken from '../sunken'
import { getComponent, render } from '../_util/props-util';
import Icon from '../icon'

const prefixCls = 'x-tag'

type SizeType = 'small' | 'medium' | 'large'
type TypeEmnu = 'default' | 'primary' | 'info' | 'success' | 'warning' | 'error'

const Tag = defineComponent({
  name: prefixCls,
  props: {
    closable: Boolean,
    closeIcon: [String, Object],
    color: String,
    icon: Object as PropType<VNodeChild>,
    round: Boolean,
    bordered: Boolean,
    nowrap: Boolean,
    size: { type: String as PropType<SizeType>, default: 'small' },
    type: { type: String as PropType<TypeEmnu>, default: 'default' },
    onClose: Function
  },
  emits: ['close'],
  directives: {
    [Sunken.name]: Sunken
  },
  setup(props, { slots, emit }) {
    function onClose(e: MouseEvent) {
      e.stopPropagation()
      emit('close', e)
    }
    function onMousedown(e: MouseEvent) {
      e.stopPropagation()
    }

    function renderCloseNode(vm) {
      let cls = `${prefixCls}-close-icon`
      if (props.closable) {
        let node, icon = props.closeIcon || 'cross'
        if (typeof icon === 'string') {
          node =  <Icon class={cls} type={icon} />
        } else {
          node = <div class={cls}>{ getComponent(vm, 'closeIcon') }</div>
        }
        node.props.onClick = onClose
        node.props.onMousedown = onMousedown
        return node
      }
    }
    
    return vm => {
      const { color, size, type } = props
      const style = { backgroundColor: color }
      const cls = [prefixCls, `${prefixCls}-${size}`, `${prefixCls}-${type}`, {
        [`${prefixCls}-round`]: props.round,
        [`${prefixCls}-bordered`]: props.bordered,
        [`${prefixCls}-nowrap`]: props.nowrap
      }]

      const iconNode = render(props.icon)

      return (
        <span class={cls} style={style} v-sunken>
          {iconNode}
          {slots.default?.()}
          {renderCloseNode(vm)}
        </span>
      )
    }
  }
})

Tag.install = (app: App) => {
  app.component(Tag.name, Tag)
}

export default Tag